package com.framework.handler;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpStatus;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.common.core.domain.entity.SysUser;
import com.common.core.domain.model.LoginUser;
import com.common.exception.ServiceException;
import com.common.utils.SecurityUtils;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Date;

/**
 * @description: 对数据库每条记录的创建时间和更新时间自动进行填充
 **/
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    /**
     * 插入时的填充策略
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        this.setFieldValByName("createDate", new Date(), metaObject);
        try {
            SysUser user = getUser();
            if (ObjectUtil.isNotNull(user)) {
                Long userId = user.getUserId();
                String userName = user.getUserName();
                // 填充创建人等信息
                this.setFieldValByName("createUserId", userId.toString(), metaObject);
                this.setFieldValByName("createUserName", userName, metaObject);
            }
        }catch (Exception e) {
            throw new ServiceException("自动注入异常 => " + e.getMessage(), HttpStatus.HTTP_UNAUTHORIZED);
        }
    }

    /**
     * 更新时的填充策略
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("lastEditDate", new Date(), metaObject);
        try {
            SysUser user = getUser();
            if (ObjectUtil.isNotNull(user)) {
                Long userId = user.getUserId();
                String userName = user.getUserName();
                this.setFieldValByName("lastEditUserId", userId.toString(), metaObject);
                this.setFieldValByName("lastEditUserName", userName, metaObject);
            }
        }catch (Exception e) {
            throw new ServiceException("自动注入异常 => " + e.getMessage(), HttpStatus.HTTP_UNAUTHORIZED);
        }

    }


    private SysUser getUser() {
        SysUser user;
        try {
            LoginUser loginUser = SecurityUtils.getLoginUser();
            user = loginUser.getUser();
        } catch (Exception e) {
            return null;
        }
        return user;
    }


    public void fillForInsert(MetaObject metaObject) {
        LocalDateTime now = LocalDateTime.now();
        this.setFieldValByName("createUserid", getUserId(), metaObject);
        this.setFieldValByName("createUsername", getUserName(), metaObject);
        this.setFieldValByName("createDate", now, metaObject);
        this.setFieldValByName("lastEditUserid", getUserId(), metaObject);
        this.setFieldValByName("lastEditUsername", getUserName(), metaObject);
        this.setFieldValByName("lastEditDate", now, metaObject);
    }

    public void fillForUpdate(MetaObject metaObject) {
        LocalDateTime now = LocalDateTime.now();
        this.setFieldValByName("lastEditUserid", getUserId(), metaObject);
        this.setFieldValByName("lastEditUsername", getUserName(), metaObject);
        this.setFieldValByName("lastEditDate", now, metaObject);
    }

    /**
     *
     * @param metaObject
     */
    public void fillForCheckX(MetaObject metaObject) {
        LocalDateTime now = LocalDateTime.now();
        this.setFieldValByName("checker", getUserName(), metaObject);
        this.setFieldValByName("checkerId", getUserId(), metaObject);
        //todo 需要获取用户组的接口
        this.setFieldValByName("checkerGroupId", "NEED INTERFACE", metaObject);
        this.setFieldValByName("moduleId", "bdrsfApplyBook", metaObject);
    }

    private String getUserName(){
        try {
            return SecurityUtils.getUsername();
        }catch(Exception ignored){
            return "获取用户名称异常";
        }
    }

    private String getUserId(){
        try {
            return SecurityUtils.getUserId().toString();
        }catch(Exception ignored){
            return "获取用户id异常";
        }
    }

    public static MetaObject getMetaObject(Object entity) {
        return org.apache.ibatis.reflection.SystemMetaObject.forObject(entity);
    }
}
